package scatter.sensitive.rest.common.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.dfa.FoundWord;
import cn.hutool.dfa.WordTree;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import scatter.sensitive.pojo.word.dto.SensitiveWordDto;
import scatter.sensitive.pojo.word.param.SensitiveWordParam;
import scatter.sensitive.pojo.word.po.SensitiveWord;
import scatter.sensitive.rest.common.ISensitiveWordFramework;
import scatter.sensitive.rest.word.service.ISensitiveWordService;

import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;

/**
 * <p>
 * 默认的敏感语框架处理实现
 * </p>
 *
 * @author yangwei
 * @since 2021-11-11 15:02
 */
public class DefaultSensitiveWordFrameworkImpl implements ISensitiveWordFramework {


	/**
	 * 有穷自动机树，存储
	 */
	private static WordTree tree = new WordTree();
	/**
	 * 最后一次更新 tree 的时间
	 */
	private static LocalDateTime lastUpdateAt = null;


	@Autowired
	private ISensitiveWordService iSensitiveWordService;
	@Qualifier("commonDbTaskExecutor")
	@Autowired
	private ExecutorService executorService;


	@Override
	public boolean isIncludeSensitiveInfo(SensitiveWordParam param) {
		appendToTreeIfNeccessary();
		return tree.isMatch(param.getContent());
	}

	@Override
	public SensitiveWordDto replaceSensitiveWord(SensitiveWordParam param) {
		appendToTreeIfNeccessary();
		List<FoundWord> foundWords = tree.matchAllWords(param.getContent());
		StringBuilder sb = new StringBuilder(param.getContent());
		if (CollectionUtil.isNotEmpty(foundWords)) {
			for (FoundWord foundWord : foundWords) {
				// 将找到的敏感词替换为 *
				sb.replace(foundWord.getStartIndex(),foundWord.getEndIndex(),"*");
			}
		}
		SensitiveWordDto sensitiveWordDto = new SensitiveWordDto();
		sensitiveWordDto.setContent(sb.toString());
		return sensitiveWordDto;
	}

	/**
	 * 增量关键词
	 */
	private void appendToTreeIfNeccessary(){
		if (lastUpdateAt == null) {
			allRefresh();
		}else {
			incrementAppend();
		}
	}

	/**
	 * 全量刷新
	 */
	private void allRefresh(){
		List<SensitiveWord> list = iSensitiveWordService.list();
		if (CollectionUtil.isNotEmpty(list)) {
			lastUpdateAt = LocalDateTime.now();
			WordTree treeTemp = new WordTree();
			treeTemp.addWords(list.stream().map(SensitiveWord::getWord).collect(Collectors.toList()));
			tree = treeTemp;
		}
	}

	/**
	 * 增量添加
	 */
	private void incrementAppend(){
		LambdaQueryWrapper<SensitiveWord> ge = Wrappers.<SensitiveWord>lambdaQuery().ge(SensitiveWord::getUpdateAt, lastUpdateAt);
		List<SensitiveWord> list = iSensitiveWordService.list(ge);
		if (CollectionUtil.isNotEmpty(list)) {
			lastUpdateAt = LocalDateTime.now();
			tree.addWords(list.stream().map(SensitiveWord::getWord).collect(Collectors.toList()));
		}
	}
}
